package com.xiaoshuidi.cloud.module.iot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.module.iot.api.device.vo.WaterMeterCommonResponseModel;
import com.xiaoshuidi.cloud.module.iot.common.ResultModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.OperateThirdDeviceRequestModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.OperateThirdDeviceResponseModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenRequestWrapperModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenResponseWrapperModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.callback.SendMessageVo;
import com.xiaoshuidi.cloud.module.iot.dal.model.watermeter.*;
import com.xiaoshuidi.cloud.module.iot.dal.model.watermeter.details.WaterMeterReportListModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.watermeter.details.WaterMeterReportRequestModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.watermeter.details.WaterMeterReportResponseModel;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.DevicePrice;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbAccountDo;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDeviceDo;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDeviceDosageDo;
import com.xiaoshuidi.cloud.module.iot.dal.repository.DeviceDosageRepository;
import com.xiaoshuidi.cloud.module.iot.dal.repository.DevicePriceRepository;
import com.xiaoshuidi.cloud.module.iot.dal.repository.DeviceRepository;
import com.xiaoshuidi.cloud.module.iot.dal.repository.TbAccountRepository;
import com.xiaoshuidi.cloud.module.iot.enums.BrandEnum;
import com.xiaoshuidi.cloud.module.iot.enums.DeviceTypeEnum;
import com.xiaoshuidi.cloud.module.iot.enums.ErrorCodeEnum;
import com.xiaoshuidi.cloud.module.iot.enums.WaterElectricityReportType;
import com.xiaoshuidi.cloud.module.iot.service.*;
import com.xiaoshuidi.cloud.module.rooms.api.sdiot.IotRoomDeviceApi;
import com.xiaoshuidi.cloud.module.rooms.vo.PriceInfo;
import com.xiaoshuidi.cloud.module.rooms.vo.RoomContractVO;
import com.xiaoshuidi.cloud.module.rooms.vo.RoomDevicePeakValleyPriceVo;
import com.xiaoshuidi.cloud.module.rooms.vo.RoomSdiotDeviceMappingVo;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;

import static com.xiaoshuidi.cloud.module.iot.dal.util.SendMqMessageUtil.compute;

/**
 * @author arvin
 * @date 2019-07-04 16:51
 * @description 第三方公共业务-水表
 */
@Service
public class WaterMeterServiceImpl implements WaterMeterService {

    private final static Logger LOGGER = LoggerFactory.getLogger(WaterMeterServiceImpl.class);

    @Autowired
    private TbAccountRepository tbAccountDataAccess;

    @Autowired
    private LocalAccessTokenServcie localAccessTokenServcie;
    @Autowired
    private DeviceRepository waterMeterDataAccess;
    @Autowired
    private DeviceDosageRepository deviceDosageDataAccess;
    @Autowired
    private DevicePriceRepository devicePriceAccess;

    @Autowired
    private IotRoomDeviceApi roomDeviceApi;
    @Resource
    private StreamBridge streamBridge;
    @Autowired
    IotRoomDeviceApi iotRoomDeviceApi;
    @Autowired
    private WaterElectricityReportService waterElectricityReportService;

    /**
     * 第三方公共业务-刷新水表
     *
     * @param waterMeterCommonResponseModel
     * @return
     */
    @Override
    public ResultModel<WaterMeterCommonResponseModel> refreshWatermeterInfo(WaterMeterCommonResponseModel waterMeterCommonResponseModel) throws Exception {
        ResultModel<WaterMeterCommonResponseModel> resultModel = null;
        ResultModel<AccessTokenResponseWrapperModel> accessTokenResultModel = this.getAccessToken(waterMeterCommonResponseModel.getApiNo());
        if (ResultModel.CODE_SUCCESS.equals(accessTokenResultModel.getCode())) {
            AccessTokenResponseWrapperModel accessTokenResultModelData = accessTokenResultModel.getData();
            ThirdInstanceService thirdInstanceService = ThirdInstanceFactory.produce(waterMeterCommonResponseModel.getBrandNo());
            OperateThirdDeviceRequestModel operateThirdDeviceRequestModel = new OperateThirdDeviceRequestModel();
            operateThirdDeviceRequestModel.setAccessToken(accessTokenResultModel.getData().getAccessToken());
            operateThirdDeviceRequestModel.setLoginName(accessTokenResultModelData.getAppId());
            operateThirdDeviceRequestModel.setLoginKey(accessTokenResultModelData.getAppKey());
            WaterMeterCommonResponseModel waterMeterCommonResponseModelNew = thirdInstanceService.refreshWatermeterInfo(waterMeterCommonResponseModel, operateThirdDeviceRequestModel);
            resultModel = ResultModel.createSuccess(waterMeterCommonResponseModelNew);
        } else {
            resultModel = ResultModel.createFail(accessTokenResultModel.getCode(), accessTokenResultModel.getMsg());
        }
        return resultModel;
    }


    /**
     * 第三方公共业务-水表退租
     *
     * @param watermeterRecedeReqVO
     * @return
     */
    @Override
    public ResultModel<WatermeterRecedeResVO> recedeWatermeter(WatermeterRecedeReqVO watermeterRecedeReqVO) throws Exception {
        ResultModel<WatermeterRecedeResVO> resultModel = null;
        ResultModel<AccessTokenResponseWrapperModel> accessTokenResultModel = this.getAccessToken(watermeterRecedeReqVO.getTbDeviceDo().getApiNo());
        if (ResultModel.CODE_SUCCESS.equals(accessTokenResultModel.getCode())) {
            ThirdInstanceService thirdInstanceService = ThirdInstanceFactory.produce(watermeterRecedeReqVO.getTbDeviceDo().getBrandNo());
            TbDeviceDo tbDeviceDo = watermeterRecedeReqVO.getTbDeviceDo();
            OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = thirdInstanceService.recedeWatermeter(new OperateThirdDeviceRequestModel().setAccessToken(accessTokenResultModel.getData().getAccessToken())
                    .setDeviceThirdNo(tbDeviceDo.getDeviceThirdNo()).setApiNo(tbDeviceDo.getApiNo()));
            resultModel = operateThirdDeviceResponseModel.getOperateResult() ? ResultModel.createSuccess() : ResultModel.createNativeFail(operateThirdDeviceResponseModel.getOperateMessage());
        } else {
            resultModel = ResultModel.createFail(accessTokenResultModel.getCode(), accessTokenResultModel.getMsg());
        }
        return resultModel;
    }

    /**
     * 第三方公共业务-水表入住
     *
     * @param watermeterRecedeReqVO
     * @return
     */
    @Override
    public ResultModel<WatermeterStayResVO> stayWatermeter(WatermeterStayReqVO watermeterRecedeReqVO) throws Exception {
        ResultModel<WatermeterStayResVO> resultModel = null;
        ResultModel<AccessTokenResponseWrapperModel> accessTokenResultModel = this.getAccessToken(watermeterRecedeReqVO.getTbDeviceDo().getApiNo());
        if (ResultModel.CODE_SUCCESS.equals(accessTokenResultModel.getCode())) {
            ThirdInstanceService thirdInstanceService = ThirdInstanceFactory.produce(watermeterRecedeReqVO.getTbDeviceDo().getBrandNo());
            TbDeviceDo tbDeviceDo = watermeterRecedeReqVO.getTbDeviceDo();
            OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = thirdInstanceService.stayWatermeter(new OperateThirdDeviceRequestModel().setAccessToken(accessTokenResultModel.getData().getAccessToken())
                    .setDeviceThirdNo(tbDeviceDo.getDeviceThirdNo()).setApiNo(tbDeviceDo.getApiNo()).setUserName(watermeterRecedeReqVO.getTenantName()).setUserMobile(watermeterRecedeReqVO.getTenantPhone()));
            resultModel = operateThirdDeviceResponseModel.getOperateResult() ? ResultModel.createSuccess() : ResultModel.createNativeFail(operateThirdDeviceResponseModel.getOperateMessage());
        } else {
            resultModel = ResultModel.createFail(accessTokenResultModel.getCode(), accessTokenResultModel.getMsg());
        }
        return resultModel;
    }

    /**
     * 根据 apiNo 获取AccessToken
     *
     * @param apiNo
     * @return
     * @throws Exception
     */
    private ResultModel<AccessTokenResponseWrapperModel> getAccessToken(String apiNo) throws Exception {
        TbAccountDo tbAccountDo = tbAccountDataAccess.getThirdApiByApiNo(apiNo);
        AccessTokenRequestWrapperModel accessTokenRequestWrapperModel = new AccessTokenRequestWrapperModel();
        accessTokenRequestWrapperModel.setApiNo(tbAccountDo.getApiNo());
        ResultModel<AccessTokenResponseWrapperModel> accessTokenResultModel = localAccessTokenServcie.getAccessToken(accessTokenRequestWrapperModel);
        return accessTokenResultModel;
    }


    /**
     * 水表用水明细
     *
     * @param waterMeterReportRequestModel
     * @return
     */
    @Override
    public ResultModel<WaterMeterReportResponseModel> getWatermeterReport(WaterMeterReportRequestModel waterMeterReportRequestModel) {
        WaterMeterCommonRequestModel waterMeterCommonRequestModel = new WaterMeterCommonRequestModel();
        waterMeterCommonRequestModel.setDeviceNo(waterMeterReportRequestModel.getDeviceNo());
        WaterMeterCommonResponseModel waterMeterCommonResponseModel = new WaterMeterCommonResponseModel();
        WaterMeterReportResponseModel waterMeterReportResponseModel = new WaterMeterReportResponseModel();
        if (waterMeterReportRequestModel.getPageNum() == null || waterMeterReportRequestModel.getPageSize() == null) {
        } else if (StrUtil.isBlank(waterMeterReportRequestModel.getDeviceNo().trim())) {
            return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_NULL.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_NULL.getMsg());
        }
        waterMeterCommonResponseModel = this.waterMeterDataAccess.getWatermeterInfoBydeviceNo(waterMeterCommonRequestModel);
        if (waterMeterCommonResponseModel == null || "".equals(waterMeterCommonResponseModel)) {
            return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getMsg());
        } else if (waterMeterCommonResponseModel.getDeviceType().equals(DeviceTypeEnum.AMMETER.getCode())) {
            return ResultModel.createFail(ErrorCodeEnum.DEVICE_BELONG_TO_AMMETER.getCode(), ErrorCodeEnum.DEVICE_BELONG_TO_AMMETER.getMsg());
        } else if (waterMeterCommonResponseModel.getDeviceType().equals(DeviceTypeEnum.DOORLOCK.getCode())) {
            return ResultModel.createFail(ErrorCodeEnum.DEVICE_BELONG_TO_DOORLOCK.getCode(), ErrorCodeEnum.DEVICE_BELONG_TO_DOORLOCK.getMsg());
        } else {
            List<WaterMeterReportListModel> waterMeterReportListModels = new ArrayList<>();

            //根据设备编号查询合同开始时间，将开始时间赋值给查询开始时间，结束时间设置为当天
            if (ObjectUtil.isEmpty(waterMeterReportRequestModel.getQueryBeginTime())) {
                ResultModel<RoomContractVO> queryResult = iotRoomDeviceApi.queryRoomContract(waterMeterReportRequestModel.getDeviceNo());
                if (ResultModel.CODE_SUCCESS.equals(queryResult.getCode())) {
                    if (null != queryResult.getData()) {
                        LocalDateTime localDateTime = queryResult.getData().getStartTime().atStartOfDay();
                        long beginTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
                        long endTimestamp = LocalDate.now().plusDays(1).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
                        waterMeterReportRequestModel.setQueryBeginTime(beginTimestamp);
                        waterMeterReportRequestModel.setQueryEndTime(endTimestamp);
                    }
                }
            }
            //查询时间间隔内的该设备的用水明细记录
            List<TbDeviceDosageDo> tbDeviceDosageDoList = deviceDosageDataAccess.getDeviceDosageByDeviceNoAndTimeNoPage(waterMeterReportRequestModel);
            //总金额
            BigDecimal allTotalAmountMoney = BigDecimal.ZERO;
            for (TbDeviceDosageDo tbDeviceDosageDo : tbDeviceDosageDoList) {
                allTotalAmountMoney = allTotalAmountMoney.add(BigDecimal.valueOf(tbDeviceDosageDo.getAmount()));
            }
            //处理分页数据
            int size = tbDeviceDosageDoList.size();
            int pageCount = size / waterMeterReportRequestModel.getPageSize();
            int fromIndex = waterMeterReportRequestModel.getPageSize() * (waterMeterReportRequestModel.getPageNum() - 1);
            int toIndex = fromIndex + waterMeterReportRequestModel.getPageSize();
            if (toIndex >= size) {
                toIndex = size;
            }
            if (waterMeterReportRequestModel.getPageNum() > pageCount + 1) {
                fromIndex = 0;
                toIndex = 0;
            }
            List<TbDeviceDosageDo> tbDeviceDosageDos = tbDeviceDosageDoList.subList(fromIndex, toIndex);
            for (TbDeviceDosageDo tbDeviceDosageDo : tbDeviceDosageDos) {
                WaterMeterReportListModel waterMeterReportListModel = new WaterMeterReportListModel();
                waterMeterReportListModel.setEndAmount(tbDeviceDosageDo.getEndAmount());
                waterMeterReportListModel.setDosageDate(tbDeviceDosageDo.getDosageDate());
                waterMeterReportListModel.setTotalAmount(tbDeviceDosageDo.getTotalAmount());
                waterMeterReportListModel.setStartAmount(tbDeviceDosageDo.getStartAmount());
                waterMeterReportListModel.setTotalAmountMoney(tbDeviceDosageDo.getAmount());
                waterMeterReportListModels.add(waterMeterReportListModel);
            }
            PageInfo<WaterMeterReportListModel> pageInfo = new PageInfo<WaterMeterReportListModel>(waterMeterReportListModels);
            pageInfo.setTotal(tbDeviceDosageDoList.size());
            waterMeterReportResponseModel.setPageInfo(pageInfo);
            waterMeterReportResponseModel.setAllTotalAmountMoney(allTotalAmountMoney.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
            return ResultModel.createSuccess(waterMeterReportResponseModel);
        }

    }

    /**
     * 设置水表停水
     *
     * @param waterMeterSwitchOnOffReqVO
     * @return
     */
    @Override
    public ResultModel<WaterMeterSwitchOnOffResVO> setWaterMeterSwitchOff(WaterMeterSwitchOnOffReqVO waterMeterSwitchOnOffReqVO) throws Exception {
        ResultModel<WaterMeterSwitchOnOffResVO> resultModel = null;
        TbDeviceDo tbDeviceDo = waterMeterDataAccess.getWatermeterInfoByDeviceNo(waterMeterSwitchOnOffReqVO.getDeviceNo());
        waterMeterSwitchOnOffReqVO.setTbDeviceDo(tbDeviceDo);
        ResultModel<AccessTokenResponseWrapperModel> accessTokenResultModel = this.getAccessToken(waterMeterSwitchOnOffReqVO.getTbDeviceDo().getApiNo());
        if (ResultModel.CODE_SUCCESS.equals(accessTokenResultModel.getCode())) {
            AccessTokenResponseWrapperModel accessTokenResultModelData = accessTokenResultModel.getData();
            ThirdInstanceService thirdInstanceService = ThirdInstanceFactory.produce(waterMeterSwitchOnOffReqVO.getTbDeviceDo().getBrandNo());
            String deviceType = waterMeterSwitchOnOffReqVO.getTbDeviceDo().getDeviceType();
            OperateThirdDeviceRequestModel operateThirdDeviceRequestModel = new OperateThirdDeviceRequestModel()
                    .setAccessToken(accessTokenResultModel.getData().getAccessToken())
                    .setDeviceThirdNo(waterMeterSwitchOnOffReqVO.getTbDeviceDo().getDeviceThirdNo())
                    .setLoginName(accessTokenResultModelData.getAppId())
                    .setLoginKey(accessTokenResultModelData.getAppKey());
            OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = null;
            if (DeviceTypeEnum.COLD_WATERMETE_TYPE_ENUM.getCode().equals(deviceType)) {
                operateThirdDeviceResponseModel = thirdInstanceService.switchColdWaterMeterOff(operateThirdDeviceRequestModel);
            } else {
                operateThirdDeviceResponseModel = thirdInstanceService.switchHotWaterMeterOff(operateThirdDeviceRequestModel);
            }

            if (operateThirdDeviceResponseModel.getOperateResult()) {
                boolean updateResult = waterMeterDataAccess.updateWaterMeterSwitchOnoff(tbDeviceDo.getDeviceNo(), 0);
                resultModel = ResultModel.createSuccess();
            } else {
                resultModel = ResultModel.createNativeFail(operateThirdDeviceResponseModel.getOperateMessage());
            }
        } else {
            resultModel = ResultModel.createFail(accessTokenResultModel.getCode(), accessTokenResultModel.getMsg());
        }
        resultModel.setData(new WaterMeterSwitchOnOffResVO().setPowerStatus(0).setDeviceNo(waterMeterSwitchOnOffReqVO.getDeviceNo()));
        return resultModel;
    }

    /**
     * 设置水表供水
     *
     * @param waterMeterSwitchOnOffReqVO
     * @return
     */
    @Override
    public ResultModel<WaterMeterSwitchOnOffResVO> setWaterMeterSwitchOn(WaterMeterSwitchOnOffReqVO waterMeterSwitchOnOffReqVO) throws Exception {
        ResultModel<WaterMeterSwitchOnOffResVO> resultModel = null;
        TbDeviceDo tbDeviceDo = waterMeterDataAccess.getWatermeterInfoByDeviceNo(waterMeterSwitchOnOffReqVO.getDeviceNo());
        waterMeterSwitchOnOffReqVO.setTbDeviceDo(tbDeviceDo);
        ResultModel<AccessTokenResponseWrapperModel> accessTokenResultModel = this.getAccessToken(waterMeterSwitchOnOffReqVO.getTbDeviceDo().getApiNo());
        if (ResultModel.CODE_SUCCESS.equals(accessTokenResultModel.getCode())) {
            AccessTokenResponseWrapperModel accessTokenResultModelData = accessTokenResultModel.getData();
            ThirdInstanceService thirdInstanceService = ThirdInstanceFactory.produce(waterMeterSwitchOnOffReqVO.getTbDeviceDo().getBrandNo());
            String deviceType = waterMeterSwitchOnOffReqVO.getTbDeviceDo().getDeviceType();
            OperateThirdDeviceRequestModel operateThirdDeviceRequestModel = new OperateThirdDeviceRequestModel()
                    .setAccessToken(accessTokenResultModel.getData().getAccessToken())
                    .setDeviceThirdNo(waterMeterSwitchOnOffReqVO.getTbDeviceDo().getDeviceThirdNo())
                    .setLoginName(accessTokenResultModelData.getAppId())
                    .setLoginKey(accessTokenResultModelData.getAppKey());
            OperateThirdDeviceResponseModel operateThirdDeviceResponseModel = null;
            if (DeviceTypeEnum.COLD_WATERMETE_TYPE_ENUM.getCode().equals(deviceType)) {
                operateThirdDeviceResponseModel = thirdInstanceService.switchColdWaterMeterOn(operateThirdDeviceRequestModel);
            } else {
                operateThirdDeviceResponseModel = thirdInstanceService.switchHotWaterMeterOn(operateThirdDeviceRequestModel);
            }

            if (operateThirdDeviceResponseModel.getOperateResult()) {
                boolean updateResult = waterMeterDataAccess.updateWaterMeterSwitchOnoff(tbDeviceDo.getDeviceNo(), 1);
                resultModel = ResultModel.createSuccess();
            } else {
                resultModel = ResultModel.createNativeFail(operateThirdDeviceResponseModel.getOperateMessage());
            }
        } else {
            resultModel = ResultModel.createFail(accessTokenResultModel.getCode(), accessTokenResultModel.getMsg());
        }
        resultModel.setData(new WaterMeterSwitchOnOffResVO().setPowerStatus(1).setDeviceNo(waterMeterSwitchOnOffReqVO.getDeviceNo()));
        return resultModel;
    }

    /**
     * 刷新水表详情
     *
     * @param waterMeterCommonRequestModel
     * @return
     */
    @Override
    public ResultModel<WaterMeterCommonResponseModel> refreshWatermeterInfo(WaterMeterCommonRequestModel waterMeterCommonRequestModel) throws Exception {
        WaterMeterCommonResponseModel waterMeterCommonResponseModel = new WaterMeterCommonResponseModel();
        ResultModel<WaterMeterCommonResponseModel> resultModel = null;
        if (StrUtil.isBlank(waterMeterCommonRequestModel.getDeviceNo().trim())) {
            return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_NULL.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_NULL.getMsg());
        } else {
            waterMeterCommonResponseModel = this.waterMeterDataAccess.getWatermeterInfoBydeviceNo(waterMeterCommonRequestModel);
            if (waterMeterCommonResponseModel == null || "".equals(waterMeterCommonResponseModel)) {
                return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getMsg());
            } else {
                //调用第三方刷新水表服务
                resultModel = this.refreshWatermeterInfo(waterMeterCommonResponseModel);
                if (ResultModel.CODE_SUCCESS.equals(resultModel.getCode())) {
                    if (resultModel.getData().getOperateResult()) {
                        BeanUtil.copyProperties(resultModel.getData(), waterMeterCommonResponseModel, new CopyOptions().setIgnoreNullValue(true));
                        String brandNo = waterMeterCommonResponseModel.getBrandNo();
                        if (null != waterMeterCommonRequestModel.getRoomId()) {
                            waterMeterCommonResponseModel.setRoomId(waterMeterCommonRequestModel.getRoomId());
                        }
                        //新增读数记录,并更新数据处理
                        this.disposeDeviceDosage(waterMeterCommonResponseModel, waterMeterCommonRequestModel.isCharging());
                    } else {
                        return ResultModel.createNativeFail("刷新水表失败，请联系厂商!");
                    }
                }
                return ResultModel.createSuccess(waterMeterCommonResponseModel);
            }
        }
    }

    @Override
    public ResultModel<WaterMeterCommonResponseModel> refreshWatermeterInfoAsync(WaterMeterCommonRequestModel waterMeterCommonRequestModel) throws Exception {
        WaterMeterCommonResponseModel waterMeterCommonResponseModel = new WaterMeterCommonResponseModel();
        ResultModel<WaterMeterCommonResponseModel> resultModel = null;
        if (StrUtil.isBlank(waterMeterCommonRequestModel.getDeviceNo().trim())) {
            return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_NULL.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_NULL.getMsg());
        } else {
            waterMeterCommonResponseModel = this.waterMeterDataAccess.getWatermeterInfoBydeviceNo(waterMeterCommonRequestModel);
            if (waterMeterCommonResponseModel == null) {
                return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getMsg());
            } else {
                //调用第三方刷新水表服务，有些厂商的刷新是异步操作的，也就是请求刷新，厂商会回调处理，所以此处不修改处理，
                resultModel = this.refreshWatermeterInfo(waterMeterCommonResponseModel);
                if (ResultModel.CODE_SUCCESS.equals(resultModel.getCode())) {
                    if (resultModel.getData().getOperateResult()) {
                        BeanUtil.copyProperties(resultModel.getData(), waterMeterCommonResponseModel, new CopyOptions().setIgnoreNullValue(true));
                        if (null != waterMeterCommonRequestModel.getRoomId()) {
                            waterMeterCommonResponseModel.setRoomId(waterMeterCommonRequestModel.getRoomId());
                        }
                    } else {
                        return ResultModel.createNativeFail("刷新水表失败，请联系厂商!");
                    }
                }
                return ResultModel.createSuccess(waterMeterCommonResponseModel);
            }
        }
    }


    /**
     * 处理刷新最新数据
     *
     * @param waterMeterCommonResponseModel
     */
    @Override
    public void disposeDeviceDosage(WaterMeterCommonResponseModel waterMeterCommonResponseModel, boolean charging) {
        TbDeviceDo currentWaterDevice = waterMeterDataAccess.getWatermeterInfoByDeviceNo(waterMeterCommonResponseModel.getDeviceNo());
        //增加水电表抄表记录，并更新水电表读数
        TbDeviceDosageDo tbDeviceDosageDo = new TbDeviceDosageDo();
        tbDeviceDosageDo.setDosageDate(LocalDate.now());
        tbDeviceDosageDo.setEndAmount(waterMeterCommonResponseModel.getCurrentReading());
        if (tbDeviceDosageDo.getEndAmount().compareTo(currentWaterDevice.getCurrentReading()) < 0) {
            return;
        }
        //第一次读数上传

        if (waterMeterCommonResponseModel.getCurrentReading().compareTo(0.0) == 0) {
            tbDeviceDosageDo.setStartAmount(tbDeviceDosageDo.getEndAmount());
        } else {
            tbDeviceDosageDo.setStartAmount(currentWaterDevice.getCurrentReading());
        }
        BigDecimal totalAmount = BigDecimal.valueOf(tbDeviceDosageDo.getEndAmount()).subtract(BigDecimal.valueOf(tbDeviceDosageDo.getStartAmount()));
        tbDeviceDosageDo.setTotalAmount(totalAmount.doubleValue());
        tbDeviceDosageDo.setDeviceNo(waterMeterCommonResponseModel.getDeviceNo());
        //获取阶梯水电价格 1.获取本年度的总度数 2.根据阶梯配置判断使用哪种价格
        Double readAllAccount = 0.0;
        Calendar now = Calendar.getInstance();
        int year = now.get(Calendar.YEAR);
        DevicePrice devicePrice = devicePriceAccess.getDevicePriceVo(Long.valueOf(year), currentWaterDevice.getDeviceNo());
        LOGGER.info("获取年度总度数数据：" + JSONObject.toJSONString(devicePrice));
        //记录总度数
        if (null == devicePrice) {
            DevicePrice devicePriceVo = new DevicePrice();
            devicePriceVo.setYear(Long.valueOf(year));
            devicePriceVo.setDeviceThireNo(currentWaterDevice.getDeviceThirdNo());
            devicePriceVo.setDeviceNo(currentWaterDevice.getDeviceNo());
            devicePriceVo.setReadAccount(tbDeviceDosageDo.getEndAmount());
            devicePriceAccess.save(devicePriceVo);
        } else {
            //更新总度数
            readAllAccount = totalAmount.add(BigDecimal.valueOf(devicePrice.getReadAccount())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            devicePrice.setReadAccount(readAllAccount);
            devicePriceAccess.updateById(devicePrice);
        }
        BigDecimal accountAmount = BigDecimal.ZERO;
        boolean isLuoSaiOrLeiYou = BrandEnum.LEIYOU.getBrand().equals(currentWaterDevice.getBrandNo()) || BrandEnum.LUOSAI.getBrand().equals(currentWaterDevice.getBrandNo());
        // 如果是罗赛或者雷优 用新的接口查询单价
        if (isLuoSaiOrLeiYou) {
            CommonResult<List<RoomDevicePeakValleyPriceVo>> result = roomDeviceApi.getDevicePeakValleyPrice(currentWaterDevice.getDeviceNo(), currentWaterDevice.getDeviceType());
            LOGGER.info("获取峰谷水电单价数据：" + JSONObject.toJSONString(result));
            if (result.isSuccess()) {
                List<RoomDevicePeakValleyPriceVo> data = result.getData();
                if (CollectionUtils.isNotEmpty(data)) {
                    RoomDevicePeakValleyPriceVo roomDevicePeakValleyPriceVo = data.get(0);
                    Double coldWorterPrice = roomDevicePeakValleyPriceVo.getColdWorterPrice();
                    // 本次金额 = 单价 * 本次用量
                    accountAmount = (coldWorterPrice == null ? BigDecimal.ZERO : new BigDecimal(coldWorterPrice.toString())).multiply(totalAmount);
                }
            }
            tbDeviceDosageDo.setAmount(accountAmount.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
        } else {
            //获取本次消费金额
            CommonResult<List<PriceInfo>> infoList = roomDeviceApi.getDevicePrice(currentWaterDevice.getDeviceNo(), currentWaterDevice.getDeviceType());
            LOGGER.info("获取阶梯水电数据：" + JSONObject.toJSONString(infoList));
            accountAmount = compute(BigDecimal.valueOf(readAllAccount).subtract(totalAmount), BigDecimal.valueOf(readAllAccount), infoList.getData());
            if (charging)
                tbDeviceDosageDo.setAmount(accountAmount.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
            else {
                tbDeviceDosageDo.setAmount(0d);
            }
        }

        String mesgId = UUID.randomUUID().toString();
        tbDeviceDosageDo.setMesgId(mesgId);
        TbDeviceDo currentDevice = new TbDeviceDo();
        currentDevice.setCurrentReading(waterMeterCommonResponseModel.getCurrentReading());
        currentDevice.setOnlineStatus(waterMeterCommonResponseModel.getOnlineStatus());
        currentDevice.setUpdateTime(tbDeviceDosageDo.getCreateTime());
        LocalDateTime ldt = LocalDateTime.ofInstant(waterMeterCommonResponseModel.getReportTime().toInstant(), ZoneOffset.UTC);
        currentDevice.setReportTime(ldt);
        currentDevice.setBrandNo(waterMeterCommonResponseModel.getBrandNo());
        currentDevice.setDeviceNo(waterMeterCommonResponseModel.getDeviceNo());
        currentDevice.setVersion(waterMeterCommonResponseModel.getVersion());
        currentDevice.setPowerStatus(waterMeterCommonResponseModel.getPowerStatus());
        //处理剩余水量
//        int updateTbDeviceRecord = waterMeterDataAccess.updateTbDeviceRecord(currentDevice);
        boolean updateTbDeviceRecord = waterMeterDataAccess.updateTbDeviceRecordAndVersion(currentDevice);
        if (updateTbDeviceRecord) {
            //新增读数上报记录
            boolean addDosageResult = deviceDosageDataAccess.save(tbDeviceDosageDo);
            ResultModel<RoomSdiotDeviceMappingVo> resultModel = iotRoomDeviceApi.getRoomInfoByDeviceNo(currentWaterDevice.getDeviceNo(), currentWaterDevice.getDeviceType());
            LOGGER.info("根据deviceNo获取房间信息：" + JSONObject.toJSONString(resultModel));
            Long roomId = resultModel.getData().getRoomHouseId();
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
                String type = WaterElectricityReportType.COLD_WATER.getCode();
                if (currentWaterDevice.getDeviceType().equals(DeviceTypeEnum.HOT_WATERMETE_TYPE_ENUM.getCode())) {
                    type = WaterElectricityReportType.HOT_WATER.getCode();
                }
                //产生报表数据
                waterElectricityReportService.save(roomId, currentDevice.getDeviceNo(), currentDevice.getDeviceThirdNo(), tbDeviceDosageDo, type, currentDevice.getTenantId());
            }
            //发送消息到钱包更新余额 罗赛和雷优后付费
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0 && charging && !isLuoSaiOrLeiYou) {
                SendMessageVo messageVo = new SendMessageVo();
                messageVo.setAmount(accountAmount.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
                messageVo.setDevice(currentWaterDevice.getDeviceNo());
                messageVo.setMsgId(mesgId);
                messageVo.setRoomId(String.valueOf(roomId));
                messageVo.setTradeTime(new Date());
                messageVo.setCharging("水费");
                LOGGER.info("发送钱包数据：" + JSONObject.toJSONString(messageVo));
                boolean send = streamBridge.send("financeAccountBalance-out-0", MessageBuilder.withPayload(messageVo).setHeader("TAGS", "DEDUCT").build());
                LOGGER.info("发送钱包返回：" + JSONObject.toJSONString(send));
            }
        }
    }

    /**
     * 根据设备编号获取电表详情
     *
     * @param waterMeterCommonRequestModel
     * @return
     */
    @Override
    public ResultModel<WaterMeterCommonResponseModel> getWatermeterInfo(WaterMeterCommonRequestModel waterMeterCommonRequestModel) {
        WaterMeterCommonResponseModel waterMeterCommonResponseModel = new WaterMeterCommonResponseModel();
        if (StrUtil.isBlank(waterMeterCommonRequestModel.getDeviceNo().trim())) {
            return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_NULL.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_NULL.getMsg());
        } else {
            waterMeterCommonResponseModel = this.waterMeterDataAccess.getWatermeterInfoBydeviceNo(waterMeterCommonRequestModel);
            if (waterMeterCommonResponseModel == null || "".equals(waterMeterCommonResponseModel)) {
                return ResultModel.createFail(ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getCode(), ErrorCodeEnum.DEVICE_NO_NOT_EXIST.getMsg());
            }
        }
        return ResultModel.createSuccess(waterMeterCommonResponseModel);
    }
}
